<script setup lang="ts">
import { ref, onBeforeMount, onMounted,nextTick } from 'vue'
import { ElMessage as message } from 'element-plus'
// import searchPanel from '@/components/SearchPanel'
// import MyTable from '@/components/Table/myTable.vue'
import tableColSetting from "@/components/tableColsSetting/tableColsSetting.vue"
import useRouteList,{actionKeys} from './routeList'
import { listToTree,setTableHeight,setFixedColumnWidth,sortTreeArr} from '@/common/utils'
import { layoutRouteName } from '@/router/config'
import Add from './add.vue'
import Update from './update.vue'
import { h } from 'vue'
import {primaryColor_rgb,primaryColorFade} from "@/theme/config"
import { useResizeLR } from "@/hooks/useResizeLR"

const columns = ref<tableColConfig[]>([
	{
		// checked:false,
		label: '路由名',
		prop: 'name',
		columnKey: 'name',
		width: 120,
		align: 'center',
	},
	{
		label: '组件路径',
		prop: 'component',
		columnKey: 'component',
		width: 150,
		// align:'center',
		showOverflowTooltip: true,
	},
	{
		label: '父级路由标题',
		prop: 'pTitle',
		columnKey: 'pTitle',
		width: 100,
		align: 'center',
	},
	{
		label: 'meta',
		prop: 'meta',
		columnKey: 'meta',
		align: 'center',
		childrenCols: [
			{
				label: '页面标题',
				prop: 'title',
				columnKey: 'title',
				width: 150,
				align: 'center',
			},
			{
				label: '菜单图标',
				prop: 'icon',
				columnKey: 'icon',
				width: 150,
				align: 'center',
			},
			{
				label: '一级菜单的排序序号',
				prop: 'rank',
				columnKey: 'rank',
				width: 150,
				align: 'center',
			},
			{
				label: '是否需要权限访问',
				prop: 'noNeedAuth',
				columnKey: 'noNeedAuth',
				width: 150,
				align: 'center',
				contentRender: (scope: any) => {
					return scope.row.noNeedAuth ? h('span', { style: { color: 'rgb(245, 108, 108)' } }, '否') : h('span', { style: { color: 'rgb(29, 165, 122)' } }, '是')
				},
			},
			{
				label: '是否缓存',
				prop: 'noKeepAlive',
				columnKey: 'noKeepAlive',
				width: 100,
				align: 'center',
				contentRender: (scope: any) => {
					return scope.row.noKeepAlive ? '否' : '是'
				},
			},
			{
				label: '是否存在菜单中',
				prop: 'onInMenu',
				columnKey: 'noInMenu',
				width: 120,
				align: 'center',
				contentRender: (scope: any) => {
					return scope.row.noInMenu ? '否' : '是'
				},
			},
			{
				label: '是否隐藏菜单',
				prop: 'hiddenMenu',
				columnKey: 'hiddenMenu',
				width: 100,
				align: 'center',
				contentRender: (scope: any) => {
					return scope.row.hiddenMenu ? '是' : '否'
				},
			},
			{
				label: '是否隐藏布局',
				prop: 'hiddenLayout',
				columnKey: 'hiddenLayout',
				width: 100,
				align: 'center',
				contentRender: (scope: any) => {
					return scope.row.hiddenLayout ? '是' : '否'
				},
			},
			{
				label: '是否固定tab页',
				prop: 'affix',
				columnKey: 'affix',
				width: 120,
				align: 'center',
				contentRender: (scope: any) => {
					return scope.row.affix ? '是' : '否'
				},
			},
			{
				label: '是否跳往外部链接',
				prop: 'link',
				columnKey: 'link',
				width: 120,
				align: 'center',
				contentRender: (scope: any) => {
					return scope.row.link ? '是' : '否'
				},
			},
		],
	},
	{
		disabled:true,
		label: '操作',
		prop: 'operation',
		columnKey: 'operation',
		align: 'center',
		fixed: 'right',
		resizable:false,
		width: 128,
	},
])
const fixedColWidth=ref<number>(1)
const treeData = ref<routeTreeNode[]>([])
const current=ref(1)
const pageSize=ref(20)
const total=ref(0)
const filterOptions=ref({})
const list=ref<routeTreeNode[]>([])
const expandedKeys = ref<string[]>([layoutRouteName])
const selectedKey = ref('')
const hasChildKeys=ref<Set<string>>(new Set([]))
// const tableRef = ref<InstanceType<typeof MyTable>>()
const tableRef = ref()
const tableHeight = ref<number>(200)
const treeHeight = ref<number>()
const searchList = ref<routeTreeNode[]>([])
const addModalVisible = ref(false)
const selectedNode = ref({} as routeTreeNode)
const updateModalVisible = ref(false)
const editNode = ref({} as routeTreeNode)
const addRef = ref<InstanceType<typeof Add>>()
const updateRef = ref<InstanceType<typeof Update>>()
const addModalIsFull=ref(false)
const updateModalIsFull=ref(false)

const searchOptions=ref<searchOptionType[]>([
	{type:'input',id:'name',props:{label:'路由名'}},
	{type:'input',id:'component',props:{label:'组件路径'}},
	{type:'input',id:'pTitle',props:{label:'父路由标题'}},
	{type:'input',id:'title',props:{label:'路由标题'}},
	{type:'select',id:'noNeedAuth',props:{label:'是否需要权限访问'},innerComponentProps:{filterable:true,selectOptions:[
			 { label: '是', value: 0,disabled:false },
			 { label: '否', value: 1,disabled:false },
	  ],
	}},
	{type:'select',id:'onInMenu',props:{label:'是否存在在菜单'},innerComponentProps:{filterable:true,selectOptions:[
			 { label: '是', value: 0,disabled:false },
			 { label: '否', value: 1,disabled:false },
	  ],
	}},
	{type:'select',id:'noKeepAlive',props:{label:'是否缓存'},innerComponentProps:{filterable:true,selectOptions:[
			 { label: '是', value: 0,disabled:false },
			 { label: '否', value: 1,disabled:false },
	  ],
	}},
])

const routeList = useRouteList()


useResizeLR({
  containerSelector: ".routeManage .container",
  leftBoxSelector: ".routeManage .container .left",
  moveBarSelector: ".routeManage .container .bar",
  rightBoxSelector: ".routeManage .container .right",
  //  lMinW:180,
  rMinW: 800,
	innerMarginW:10,
})
onBeforeMount(() => {
	getPageList()
	getTreeData()
})
onMounted(() => {
	fixedColWidth.value=setFixedColumnWidth([actionKeys.update,actionKeys.delete],columns)
})
async function getPageList(){
	const res=await routeList.getPageList({page:{page:current.value,size:pageSize.value},cdt:filterOptions.value})
	if(res.code){
		// console.log(res)
      list.value=res.data.list
			total.value=res.data.total
	}
}
// 如果页面未使用 search-panel 组件，请在挂载钩子设置表格高度
function handleSearchPanelcollapsed(h:number){
  setTableHeight({tableHeightRef:tableHeight,otherSectionHeight:h}) 
	
  setTableHeight({tableHeightRef:treeHeight,otherSectionHeight:h+52,isTable:false})
  //52是表格上面工具栏的高度,h是searchPanel组件的高度
}
async function getTreeData(list = routeList.list) {
	const res = await routeList.getList()
	if (res.code) {
	  const tree = listToTree(list, 'id', 'pId', false, (i) => {
			if (i.component) i.class = 'greenText'
		},(j=>{hasChildKeys.value.add(j.name)})) as routeTreeNode
		// console.log(tree,[...list])
		treeData.value = sortTreeArr([tree],'rank')
		// console.log(tree)
	}
}

function handleSearch(value:any){
	getPageList()
}

function reset() {
	selectedKey.value = ''
	getPageList()
	tableRef.value?.reset()
}

function handleSelectTreeNode(node: routeTreeNode) {
	// console.log(node)
	searchList.value = routeList.list.filter((v) => v.name == node.name)
	selectedNode.value = node
	selectedKey.value = node.name
	//getTreeData()
	//console.log({...selectedNode.value})
}

function handleAdd() {
	if (!selectedKey.value) {
		message.warning('请先在左侧树选择父节点')
		return
	}
	if (selectedNode.value.component) {
		message.warning('选中的是叶子节点，不可添加子路由')
		return
	}
	if (selectedNode.value.link) {
		message.warning('选中的是外部链接，不可添加子路由')
		return
	}
	addModalVisible.value = true
	nextTick(() => {
		addRef.value?.init()
	})
}
async function handleAddCommit() {
	const isSuccess = await addRef.value?.formCommit()
	if (isSuccess) {
		addModalVisible.value = false
		message.success('新增成功')
		getPageList()
		getTreeData()
	}
}
function handleUpdate(row: routeTreeNode) {
	//console.log(row)
	editNode.value = row
	updateModalVisible.value = true
	nextTick(() => {
		updateRef.value?.init()
	})
}
async function handleUpdateCommit() {
	const isSuccess = await updateRef.value?.formCommit()
	if (isSuccess) {
		updateModalVisible.value = false
		message.success('更新成功')
		getTreeData()
		getPageList()
	}
}
async function handleDelete(row: routeTreeNode) {
	const res = await routeList.deleteItem({ id: row.id})
	if (res && res.code) {
		message.success('删除成功')
		// selectedKey.value = ''
		getTreeData()
		getPageList()
	}
}
function handleColumnsChange(list:tableColConfig[]){
	columns.value=list
}
function customNodeClass(data: routeItemConfig, node: Node) {
	if (data.component || data.link) {
		return 'leafTextColor'
	}
	return null
}
function nodeContentRender(h: any, e: any) {
	// console.log(h,e)
	//console.log(e)
	if (selectedKey.value == e.data.name) return h('span', { style: { backgroundColor: primaryColorFade(0.5) } }, e.data.title)
	else return e.data.title
}

</script>

<template>
	<div class="routeManage">
		<search-panel @collapsed="handleSearchPanelcollapsed"  @search="handleSearch" @reset="reset" :options="searchOptions" />
		<div class="container" style="display: flex">
			<div class="left" :style="{ height: treeHeight + 'px', }">
				<el-scrollbar >
					<el-tree
						:render-content="nodeContentRender"
						:expand-on-click-node="false"
						:props="{ children: 'children', label: 'title', class: customNodeClass }"
						node-key="name"
						:data="treeData"
						:default-expanded-keys="expandedKeys"
						@node-click="handleSelectTreeNode"
					/>
				</el-scrollbar>
			</div>
			<div class="bar" :style="{ height: treeHeight + 'px', }"></div>
			<div class="right" >
				<div class="tableTool">
					<el-button type="primary" style="margin-right: 5px" @click="handleAdd" v-if="$hasAuth([actionKeys.add])">新增子路由</el-button>
					<tableColSetting :list="columns" :fixedColWidth="fixedColWidth" @confirm="handleColumnsChange" />
				</div>
				<!-- 加上border属性，所有列将可以调整宽度 -->
				<my-table
				  border
					:data="list"
					:columns="columns"
					size="small"
					style="width: 100%"
					class="myTable"
					rowKey="name"
					:maxHeight="tableHeight"
					:pagination="{
						pageSizes: [3,5,10, 20, 30, 40, 50],    
						small: true,
						background: true,
						layout: 'total, sizes, prev, pager, next, jumper',
						total,
						onCurrentChange:(pageNum:number)=>{current=pageNum},
						onSizeChange:(size:number)=>{pageSize=size},
					}"
					ref="tableRef"
				>
				<template #operation="{ row }">
						<el-button type="primary" size="small" @click="handleUpdate(row)" v-if="$hasAuth([actionKeys.update])" :disabled="row.name==layoutRouteName">修改</el-button>
						<el-popconfirm title="确定要删除吗?" confirm-button-text="确定" cancel-button-text="取消" @confirm="handleDelete(row)" v-if="$hasAuth([actionKeys.delete])">
							<template #reference><el-button type="danger" size="small" :disabled="[...hasChildKeys].includes(row.name)" >删除</el-button></template>
						</el-popconfirm>
					</template>
				</my-table>
			</div>
		</div>

		<el-dialog v-model="addModalVisible" title="新增子路由" width="80%" :modal="false" draggable :close-on-click-modal="false" align-center :fullscreen="addModalIsFull">
			<el-scrollbar :maxHeight="addModalIsFull?0:$getDialogBodyMaxHeight()">
				<!--  套个div防止无论何时都出现横向滚动 -->
				<div style="padding: 0 10px;">
					<Add :parentNode="(selectedNode as any)" ref="addRef" />
				</div>
			</el-scrollbar>
			<template #footer>
				<div class="dialog-footer" style="display: flex;justify-content: flex-end;">
					<screenFullToggleIcon @toggle="(v:boolean)=>{addModalIsFull=v}" />
					<el-button @click="addModalVisible = false">取消</el-button>
					<el-button type="primary" @click="handleAddCommit">确定</el-button>
				</div>
			</template>
		</el-dialog>

		<el-dialog v-model="updateModalVisible" title="更新子路由" width="80%" :modal="false" draggable :close-on-click-modal="false" align-center :fullscreen="updateModalIsFull">
			<el-scrollbar :maxHeight="updateModalIsFull?0:$getDialogBodyMaxHeight()">
			 <div style="padding: 0 10px;">
			   <Update :editNode="(editNode as any)" ref="updateRef" />
			 </div>
			</el-scrollbar>
			<template #footer>
				<div class="dialog-footer" style="display: flex;justify-content: flex-end;">
					<screenFullToggleIcon @toggle="(v:boolean)=>{updateModalIsFull=v}" />
					<el-button @click="updateModalVisible = false">取消</el-button>
					<el-button type="primary" @click="handleUpdateCommit">确定</el-button>
				</div>
			</template>
		</el-dialog>
	</div>
</template>

<style scoped lang="scss">
.routeManage{

	.container {
    .left {
      overflow:hidden auto;
      margin-top: 52px;
      background-color: white;
      width: 180px;
			flex-shrink: 0;
    }
    .bar {
      width: 5px;
      background-color: gainsboro;
      margin: 52px 0 0 10px;
      background-clip: content-box;
      padding: 0 2px;
			flex-shrink: 0;
    }
	.right{
		padding-left: 20px; 
		width: calc(100% - 180px - 15px)
	}
  }

	.tableTool {
	padding: 10px 0;
	display: flex;
	justify-content: flex-end;
	align-items: center;
}
:deep(.el-table thead .el-table__cell) {
		text-align: center ;
		// background-color: rgb(232, 246, 241) !important;
}
}
</style>
